#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <string>
#include "LockGuard.hpp"

const int num = 5;   // 创建5个线程
int tickets = 10000; // 1W张票

class customer
{
public:
    customer(const std::string &name, pthread_mutex_t& mutex)
        : _name(name), _mutex(mutex)
    {}

    std::string getName()
    {
        return _name;
    }

    pthread_mutex_t &getMutex()
    {
        return _mutex;
    }

private:
    std::string _name;      // 线程的名字
    pthread_mutex_t& _mutex; // 互斥锁
};

void *route(void *args)
{
    customer *cum = static_cast<customer *>(args);
    while (true)
    {
        // 对访问共享资源的前后加锁
        //pthread_mutex_lock(&cum->getMutex());
        LockGuard lock(cum->getMutex());// 加锁
        // 临界区
        if (tickets > 0)
        {
            usleep(1000); // 模拟抢票
            std::cout << cum->getName() << ", 抢到了第" << tickets << "票" << std::endl;
            tickets--;
            // 临界区
            //pthread_mutex_unlock(&cum->getMutex()); // 当访问结束了就解锁
        }
        else
        {
            // pthread_mutex_unlock(&cum->getMutex()); // 当访不符合条件就解锁
            break;
        }
    }

    return nullptr;
}

int main()
{
    pthread_mutex_t mutex; // 定义一把局部的互斥锁
    pthread_mutex_init(&mutex, nullptr);//初始化

    std::vector<customer *> cusm; // 管理线程
    std::vector<pthread_t> tids; // 管理线程
    for (int i = 0; i < num; i++)
    {
        std::string name = "thread_" + std::to_string(i + 1);
        pthread_t tid;
        customer *cum = new customer(name, mutex);
        pthread_create(&tid, nullptr, route, (void *)cum);// 创建线程
        cusm.emplace_back(cum);
        tids.emplace_back(tid);
    }

    for (auto &tid : tids)
    {
        pthread_join(tid, nullptr);// 等待线程结束
    }

    for(auto& e : cusm)
    {
        delete e;// 释放资源
    }

    pthread_mutex_destroy(&mutex);// 释放锁

    return 0;
}










// #include <iostream>
// #include <string>
// #include <pthread.h>
// #include <unistd.h>
// #include <vector>

// const int num = 5;   // 创建5个线程
// int tickets = 10000; // 1W张票

// class customer
// {
// public:
//     customer(const std::string &name, pthread_mutex_t &mutex)
//         : _name(name), _mutex(mutex) 
//     {}

//     std::string getName() 
//     {
//         return _name;
//     }

//     pthread_mutex_t &getMutex()
//     {
//         return _mutex;
//     }

// private:
//     std::string _name;       // 线程的名字
//     pthread_mutex_t &_mutex; // 引用外部的互斥锁
// };

// void *route(void *args)
// {
//     customer *cum = static_cast<customer *>(args);
//     while (true)
//     {
//         pthread_mutex_lock(&cum->getMutex());

//         if (tickets > 0)
//         {
//             usleep(1000); // 模拟抢票
//             std::cout << cum->getName() << ", 抢到了第" << tickets << "票" << std::endl;
//             tickets--;
//             pthread_mutex_unlock(&cum->getMutex());
//         }
//         else
//         {
//             pthread_mutex_unlock(&cum->getMutex());
//             break;
//         }
//     }

//     return nullptr;
// }

// int main()
// {
//     pthread_mutex_t mutex; // 定义一把全局的互斥锁
//     pthread_mutex_init(&mutex, nullptr);

//     std::vector<pthread_t> tids;       // 管理线程ID
//     std::vector<customer *> customers; // 管理customer对象

//     for (int i = 0; i < num; i++)
//     {
//         std::string name = "thread_" + std::to_string(i + 1);
//         customer *cum = new customer(name, mutex);
//         pthread_t tid;
//         pthread_create(&tid, nullptr, route, (void *)cum);
//         tids.emplace_back(tid);
//         customers.emplace_back(cum);
//     }

//     for (auto tid : tids)
//     {
//         pthread_join(tid, nullptr);// 等待线程
//     }

//     for (auto customer : customers)
//     {
//         delete customer;// 释放资源
//     }

//     pthread_mutex_destroy(&mutex);//释放锁

//     return 0;
// }